﻿using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Drawing;
using log4net;
using System.Reflection;
namespace AnguaRPGEngine.Library.Systems
{
    public class ImageLibrary
    {
        private static readonly ILog _Log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
        public static ImageLibrary Instance = new ImageLibrary();
        private List<LibraryImage> _Library = new List<LibraryImage>();
        public override string ToString()
        {
            string MethodName = MethodBase.GetCurrentMethod().Name;
            StringBuilder sb = new StringBuilder();
            try
            {
                _Log.DebugFormat("{0} - Entry", MethodName);
                sb.AppendFormat("Total Images In Library: {0}\r\n", _Library.Count);
                foreach (LibraryImage li in _Library)
                {
                    sb.AppendFormat("{0} ({1}, {2})\r\n", li.Name, li.Image.Size.Width, li.Image.Size.Height);
                }
            }
            catch (Exception err)
            {
                _Log.Error(MethodName, err);
            }
            finally
            {
                _Log.DebugFormat("{0} - Exit", MethodName);
            }
            return sb.ToString();
        }
        public void LoadImageLibrary(string PathToLibrary)
        {
            string MethodName = MethodBase.GetCurrentMethod().Name;
            try
            {
                _Log.DebugFormat("{0} - Entry", MethodName);
                if (PathToLibrary.StartsWith("."))
                {
                    string p = Directory.GetCurrentDirectory();
                    while (PathToLibrary.Substring(0, 1) == ".")
                    {
                        p = p.Substring(0, p.LastIndexOf("\\"));
                        PathToLibrary = PathToLibrary.Remove(0, 1);
                    }
                    p += PathToLibrary;
                    PathToLibrary = p;
                }
                if (!PathToLibrary.EndsWith("\\"))
                {
                    PathToLibrary += "\\";
                }
                string[] files = Directory.GetFiles(PathToLibrary, "*.*", SearchOption.AllDirectories);
                foreach (string file in files)
                {
                    if (file.ToLower().EndsWith(".png") || file.ToLower().EndsWith(".jpg"))
                    {
                        AddImageToLibrary(PathToLibrary, file);
                    }
                }
            }
            catch (Exception err)
            {
                _Log.Error(MethodName, err);
            }
            finally
            {
                _Log.DebugFormat("{0} - Exit", MethodName);
            }
        }
        public bool AddImageToLibrary(string PathToLibrary, string FileSpec)
        {
            string MethodName = MethodBase.GetCurrentMethod().Name;
            try
            {
                _Log.DebugFormat("{0} - Entry", MethodName);
                string name = FileSpec.Replace(PathToLibrary, "").Replace("\\", ".");
                name = name.Substring(0, name.LastIndexOf("."));
                Bitmap image = (Bitmap)Image.FromFile(FileSpec);
                _Library.Add(new LibraryImage(name, image));
            }
            catch (Exception err)
            {
                _Log.Error(MethodName, err);
                _Log.Error(MethodName, new Exception("PathToLibrary: \"" + PathToLibrary + "\" - FileSpec: \"" + FileSpec + "\""));
                return false;
            }
            finally
            {
                _Log.DebugFormat("{0} - Exit", MethodName);
            }
            return true;
        }
        public Bitmap GetImageFromLibrary(string name)
        {
            string MethodName = MethodBase.GetCurrentMethod().Name;
            try
            {
                _Log.DebugFormat("{0} - Entry", MethodName);
                return new Bitmap(_Library.Find(p => p.Name == name).Image);
            }
            catch (Exception err)
            {
                _Log.Error(MethodName, err);
                _Log.Error(MethodName, new Exception("Could Not Find Image \"" + name + "\""));
                return new Bitmap(1, 1);
            }
            finally
            {
                _Log.DebugFormat("{0} - Exit", MethodName);
            }
        }
        public Bitmap GetImageFromLibrary(string name, int ShadowDistance, bool SolidShadow)
        {
            string MethodName = MethodBase.GetCurrentMethod().Name;
            try
            {
                _Log.DebugFormat("{0} - Entry", MethodName);
                Bitmap bitmap = new Bitmap(_Library.Find(p => p.Name == name).Image);
                Color ShadowColor = Color.FromArgb(180, 0, 0, 0);
                Brush ShadowBrush = new SolidBrush(ShadowColor);
                Bitmap bitmapWithShadow = new Bitmap(bitmap.Width + ShadowDistance, bitmap.Height + ShadowDistance);
                using (Graphics g = Graphics.FromImage(bitmapWithShadow))
                {
                    if (SolidShadow)
                    {
                        g.Clear(ShadowColor);
                    }
                    else
                    {
                        g.FillRectangle(ShadowBrush, new Rectangle(ShadowDistance, ShadowDistance, bitmap.Width, bitmap.Height));
                    }
                    g.DrawImage(bitmap, new Point(0, 0));
                }
                return bitmapWithShadow;
            }
            catch (Exception err)
            {
                _Log.Error(MethodName, err);
                return new Bitmap(1, 1);
            }
            finally
            {
                _Log.DebugFormat("{0} - Exit", MethodName);
            }
        }
        public Bitmap GetImageFromLibrary(string name, int ShadowDistance, bool SolidShadow, string ID, Point IDLocation)
        {
            string MethodName = MethodBase.GetCurrentMethod().Name;
            try
            {
                _Log.DebugFormat("{0} - Entry", MethodName);
                Bitmap bitmap = new Bitmap(_Library.Find(p => p.Name == name).Image);
                Color ShadowColor = Color.FromArgb(180, 0, 0, 0);
                Brush ShadowBrush = new SolidBrush(ShadowColor);
                Bitmap bitmapWithShadow = new Bitmap(bitmap.Width + ShadowDistance, bitmap.Height + ShadowDistance);
                using (Graphics g = Graphics.FromImage(bitmapWithShadow))
                {
                    if (SolidShadow)
                    {
                        g.Clear(ShadowColor);
                    }
                    else
                    {
                        g.FillRectangle(ShadowBrush, new Rectangle(ShadowDistance, ShadowDistance, bitmap.Width, bitmap.Height));
                    }
                    g.DrawImage(bitmap, new Point(0, 0));
                    g.DrawString(ID, new Font(FontFamily.GenericMonospace, 8f, FontStyle.Regular), new SolidBrush(Color.Black), IDLocation);
                }
                return bitmapWithShadow;
            }
            catch (Exception err)
            {
                _Log.Error(MethodName, err);
                return new Bitmap(1, 1);
            }
            finally
            {
                _Log.DebugFormat("{0} - Exit", MethodName);
            }
        }
        public Bitmap GetImageFromLibrary(string name, Size newSize)
        {
            string MethodName = MethodBase.GetCurrentMethod().Name;
            try
            {
                _Log.DebugFormat("{0} - Entry", MethodName);
                return new Bitmap(_Library.Find(p => p.Name == name).Image, newSize);
            }
            catch (Exception err)
            {
                _Log.Error(MethodName, err);
                return new Bitmap(1, 1);
            }
            finally
            {
                _Log.DebugFormat("{0} - Exit", MethodName);
            }
        }
        public Bitmap GetImageFromLibrary(string name, float percentOfSize)
        {
            string MethodName = MethodBase.GetCurrentMethod().Name;
            try
            {
                _Log.DebugFormat("{0} - Entry", MethodName);
                return new Bitmap(_Library.Find(p => p.Name == name).Image, new Size((int)((float)_Library.Find(p => p.Name == name).Image.Size.Width * percentOfSize), (int)((float)_Library.Find(p => p.Name == name).Image.Size.Height * percentOfSize)));
            }
            catch (Exception err)
            {
                _Log.Error(MethodName, err);
                return new Bitmap(1, 1);
            }
            finally
            {
                _Log.DebugFormat("{0} - Exit", MethodName);
            }
        }
    }


    public class LibraryImage
    {
        public string Name;
        public Bitmap Image;
        public LibraryImage(string name, Bitmap image)
        {
            this.Name = name;
            this.Image = image;
        }
    }
}